//
// Created by 33145 on 2023/4/20.
//
#include "sylar/log.h"
#include "sylar/mysql/mysql_connection_pool.h"
#include "sylar/http/http_server.h"

#include <iostream>

static sylar::sql::ConnectionPool* g_conn_pool;
static sylar::Logger::ptr g_logger = SYLAR_LOG_ROOT();
std::map<std::string, std::string> g_username_passwd;

void init() {
  g_conn_pool = sylar::sql::ConnectionPool::GetInstance();
  g_conn_pool->init("root", "1234", 5, "orange", "101.43.251.60");
  sylar::sql::MySQL::ptr mysql;
  sylar::sql::connectionRAII temp(&mysql, g_conn_pool);

  auto res = sylar::sql::MySQL::my_mysql_query(mysql, "select * from user_info");
  int num = mysql_num_rows(res);
  for (int i = 0; i < num; i++) {
    MYSQL_ROW r = mysql_fetch_row(res);
    g_username_passwd[r[0]] = r[1];
  }
}

std::pair<std::string, std::string> getKeyAndValue(const std::string& s) {
  int idx = 0;
  int n = s.size();
  while(s[idx] != '=') {
    ++idx;
  }
  return std::make_pair(s.substr(0, idx), s.substr(idx + 1, n - idx));
}

std::map<std::string, std::string> parserFormText(const std::string& ss) {
  /// type=Login&user=gezi&password=12345
  std::map<std::string, std::string> res;
  std::string s = ss;
  s.append(1, '&');
  int n = s.size();
  for (int i = 0, idx = 0; i < n;) {
    auto r = s.find('&', i);
    if (r != std::string::npos) {
      res.insert(getKeyAndValue(s.substr(idx, r - idx)));
      idx = r + 1;
      i = r + 1;
    }
  }
  return res;
}

void run() {
  g_logger->setLevel(sylar::LogLevel::INFO);
  sylar::http::HttpServer::ptr server(new sylar::http::HttpServer(true));
  sylar::Address::ptr addr = sylar::Address::LookupAnyIPAddress("0.0.0.0:9000");
  while(!server->bind(addr)) {
    sleep(2);
  }
  auto sd = server->getServletDispatch();

  sd->addServlet("/", [](sylar::http::HttpRequest::ptr req,
                         sylar::http::HttpResponse::ptr rsp,
                         sylar::http::HttpSession::ptr session) ->int32_t {
    std::ifstream ifs("/home/orange/workspace/html/log.html");
    if(!ifs) {
      rsp->setBody("invalid file");
      rsp->setStatus(sylar::http::HttpStatus::NOT_FOUND);
      return 0;
    }
    std::stringstream ss;
    std::string line;
    while(std::getline(ifs, line)) {
      //SYLAR_LOG_INFO(g_logger) << line;
      ss << line << std::endl;
    }
    rsp->setBody(ss.str());
    rsp->setHeader("content-type", "text/html;charset=utf-8");
    return 0;
  });


  sd->addServlet("/Login", [](sylar::http::HttpRequest::ptr req,
                              sylar::http::HttpResponse::ptr rsp,
                              sylar::http::HttpSession::ptr session) ->int32_t {
    /// admin_test_value  admin_test_passwd
    /// type=Login&user=gezi&password=12345
    std::ifstream ifs;

    auto res = parserFormText(req->getBody());
    SYLAR_LOG_INFO(g_logger) << req->getBody();
    SYLAR_LOG_INFO(g_logger) << res["user"] << "   " << res["password"];

    if (res["type"] == "Login") {
      auto it = g_username_passwd.find(res["user"]);
      if (it != g_username_passwd.end() && it->second == res["password"]) {
        /// 用户名和密码都正确
        ifs.open("/home/orange/workspace/html/website.html");
      } else {
        ifs.open("/home/orange/workspace/html/logError.html");
      }
    } else if (res["type"] == "register"){
      auto it = g_username_passwd.find(res["user"]);
      if (it != g_username_passwd.end()) {
        /// 用户名已被占用
        ifs.open("/home/orange/workspace/html/registerError.html");
      } else {
        ifs.open("/home/orange/workspace/html/log.html");
        sylar::sql::MySQL::ptr mysql;
        sylar::sql::connectionRAII temp(&mysql, g_conn_pool);
        mysql->execute("insert into user_info values('" + res["user"] + "', '" + res["password"] + "')");
        if (!mysql->hasError()) {
          /// 如果写回没错误，就把用户注册到数据库里
          g_username_passwd[res["user"]] = res["password"];
        } else {
          SYLAR_LOG_ERROR(g_logger) << "mysql insert has error!";
        }
      }
    }
    if(!ifs) {
      rsp->setBody("invalid file");
      rsp->setStatus(sylar::http::HttpStatus::NOT_FOUND);
      return 0;
    }
    std::stringstream ss;
    std::string line;
    while(std::getline(ifs, line)) {
      //SYLAR_LOG_INFO(g_logger) << line;
      ss << line << std::endl;
    }
    rsp->setHeader("Content-Type", "text/html;charset=utf-8");
    rsp->setBody(ss.str());
    SYLAR_LOG_INFO(g_logger) << "to this ? ";
    return 0;
  });

  sd->addServlet("/Register", [](sylar::http::HttpRequest::ptr req,
                              sylar::http::HttpResponse::ptr rsp,
                              sylar::http::HttpSession::ptr session) ->int32_t {
    std::ifstream ifs("/home/orange/workspace/html/register.html");
    if(!ifs) {
      rsp->setBody("invalid file");
      rsp->setStatus(sylar::http::HttpStatus::NOT_FOUND);
      return 0;
    }
    std::stringstream ss;
    std::string line;
    while(std::getline(ifs, line)) {
      //SYLAR_LOG_INFO(g_logger) << line;
      ss << line << std::endl;
    }
    rsp->setBody(ss.str());
    rsp->setHeader("content-type", "text/html;charset=utf-8");
    return 0;
  });

  server->start();
}

int main() {
  init();

  sylar::IOManager iom(2);
  iom.schedule(run);
  return 0;
}